package com.illtamer.infinite.collapsar.server.smtp;

import com.illtamer.infinite.collapsar.common.CollapsarConfiguration;
import com.illtamer.infinite.collapsar.common.dao.EmailDao;
import com.illtamer.infinite.collapsar.common.entity.Email;
import com.illtamer.infinite.collapsar.server.handler.Handler;
import com.illtamer.infinite.derive.configuration.file.YamlConfiguration;
import io.netty.channel.Channel;
import lombok.SneakyThrows;

import java.text.SimpleDateFormat;
import java.util.Locale;

public class DataHandler implements Handler {

    private final EmailDao emailDao = new EmailDao(CollapsarConfiguration.dataSource);

    private final TransferContext context;

    private String linePrefix;

    private final StringBuilder lineBuilder = new StringBuilder();

    private boolean bodyTag = false;

    public DataHandler(TransferContext context) {
        this.context = context;
    }

    @Override
    public void handle(String message, Channel channel) {
        if (".".equals(message.trim())) { // end
            context.setFinishData(false);
            // clear cache
            context.getConfiguration().set(linePrefix, lineBuilder.toString());
            lineBuilder.setLength(0);
            linePrefix = null;
            bodyTag = false;
            channel.writeAndFlush("250\r\n");
            System.out.printf("收到邮件：\n%s", context.getConfiguration().saveToString());
            // save to database
            parseEmail(context.getConfiguration(), context.getEmail());
            emailDao.insert(context.getEmail());
        } else {
            doHandle(message);
        }
    }

    private void doHandle(String message) {
        if (bodyTag) {
            lineBuilder.append(message);
            return;
        }
        if (message.length() == 0) {
            context.getConfiguration().set(linePrefix, lineBuilder.toString());
            linePrefix = "Content";
            lineBuilder.setLength(0);
            bodyTag = true;
            return;
        }
        // check parameter
        if (message.contains(": ")) {
            // line end
            if (linePrefix != null) {
                context.getConfiguration().set(linePrefix, lineBuilder.toString());
                lineBuilder.setLength(0);
            }

            String[] split = message.split(": ");
            linePrefix = split[0];
            lineBuilder.append(split.length != 1 ? split[1] : null);
        } else {
            lineBuilder.append(message.trim());
        }
    }

    private static final SimpleDateFormat FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);

    @SneakyThrows
    private static void parseEmail(YamlConfiguration configuration, Email email) {
        email.setFrom(configuration.getString("From"));
        email.setTo(configuration.getString("To"));
        email.setSubject(configuration.getString("Subject"));
        email.setDate(FORMAT.parse(configuration.getString("Date")));
        email.setContent(configuration);
        // nullable
        email.setSender(configuration.getString("Sender", email.getFrom()));
        email.setReplyTo(configuration.getString("Reply-To", email.getFrom()));
        email.setCc(configuration.getString("Cc", ""));
        email.setBcc(configuration.getString("Bcc", ""));
        email.setComments(configuration.getString("Comments", ""));
        email.setKeywords(configuration.getString("Keywords", ""));
        email.setInReplyTo(configuration.getInt("InReplyTo", -1));
        email.setReferences(configuration.getInt("References", -1));
        email.setEncrypted(configuration.getString("encrypted", ""));
    }

}
